package com.mvvmhabit.org.base

import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import com.mvvmhabit.org.bus.Messenger
import com.mvvmhabit.org.custom.load.LoadDialog
import com.mvvmhabit.org.utils.DisplayUtil
import com.mvvmhabit.org.utils.ToastUtils

/**
 *
 * @author 逍遥
 * @Date 2019/12/31
 *
 */
abstract class BaseActivity<V : ViewDataBinding, VM : BaseViewModel> : AppCompatActivity(),
    IBaseView {
    // 定义可以全局可以访问的 binding
    lateinit var mBinding: V
    var mViewModel: VM? = null
    private var viewModelId: Int = 0

    /**
     * 有返回值的抽象方法：得到布局文件
     * @return layoutId 的 layout
     */
    // https://developer.android.com/topic/libraries/architecture/lifecycle
    abstract fun layoutId(savedInstanceState: Bundle?): Int

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    abstract fun initVariableId(): Int

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    abstract fun initViewModel(): Class<VM>

    override fun onCreate(savedInstanceState: Bundle?) {
        // 适配方案
        DisplayUtil.setCustomDensity(this, application)
        super.onCreate(savedInstanceState)
        // BaseApplication.addActivity(this)
        initParam()
        mBinding = DataBindingUtil.setContentView(this, layoutId(savedInstanceState))
        if (mViewModel == null) {
            val simpleName = this::class.simpleName
            mViewModel = ViewModelProvider(this).get(simpleName!!, initViewModel())
            viewModelId = initVariableId()
            mBinding.setVariable(viewModelId, mViewModel)
            lifecycle.addObserver(mViewModel!!)
            mViewModel?.injectLifecycleProvider(this)
            registerUIChangeLiveEventCallBack()
            initData()
            initViewObservable()
        }
        mViewModel?.registerBus()
    }

    override fun initParam() {

    }

    override fun initData() {
    }

    override fun initViewObservable() {

    }

    override fun initStatusBar() {

    }

    private fun registerUIChangeLiveEventCallBack() {
        // 页面跳转
        mViewModel?.getUI()?.getStartActivityEvent()?.observeForever {
            val clz: Class<*> = it[CLASS] as Class<*>
            val bundle: Any? = it[BUNDLE]
            startActivity(clz, bundle)
        }
        // 跳转到容器页面
        mViewModel?.getUI()?.getStartContainerActivityEvent()?.observeForever {
            val canonicalName = it[CANONICAL_NAME] as String
            val bundle = it[BUNDLE]
            startContainerActivity(canonicalName, bundle)
        }
        // 关闭界面
        mViewModel?.getUI()?.getFinishEvent()?.observeForever {
            finish()
        }

        mViewModel?.getUI()?.getStartIntentEvent()?.observeForever {
            startActivity(it)
        }

        mViewModel?.getUI()?.getDismissLoadDialogEvent()?.observeForever {
            dismissLoadDialog()
        }

        mViewModel?.getUI()?.getShowLoadDialogEvent()?.observeForever {
            if (TextUtils.isEmpty(it)) {
                showLoadDialog()
            } else {
                showLoadDialog(it)
            }
        }
    }

    protected fun startActivity(clz: Class<*>, bundle: Any?) {
        val intent = Intent(this, clz)
        if (bundle != null) {
            intent.putExtras(bundle as Bundle)
        }
        startActivity(intent)
    }

    protected fun startContainerActivity(canonicalName: String?, bundle: Any?) {
        val intent = Intent(this, ContainerActivity::class.java)
        intent.putExtra(FRAGMENT, canonicalName)
        if (bundle != null) {
            intent.putExtra(FRAGMENT_BUNDLE, bundle as Bundle)
        }
        startActivity(intent)
    }

    override fun onDestroy() {
        super.onDestroy()
        Messenger.getDefault().unregister(mViewModel)
        if (mViewModel != null) {
            mViewModel?.removeBus()
        }
        mBinding.unbind()
        LoadDialog.destroy()
        //  BaseApplication.removeActivity(this)
    }

    private fun showLoadDialog(title: String) {
        LoadDialog.show(this, title)
    }

    private fun showLoadDialog() {
        LoadDialog.show(this, null)
    }

    private fun dismissLoadDialog() {
        LoadDialog.dismiss()
    }



}